package com.oauth2_security.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

/**
 * 
 * @author dinghao
 *
 */
@Component
@EnableResourceServer
public class SecurityConfig extends ResourceServerConfigurerAdapter {

    @Autowired
    private AuthenticationSuccessHandler adminAuthenticationSuccessHandler;

    @Autowired
    private AuthenticationFailureHandler adminAuthenticationFailureHandler;

    @Autowired
    private OAuth2WebSecurityExpressionHandler expressionHandler;

    /**
     * 声明一个Bean，该Bean主要用于spring secrity拿到用户对象password后进行matches匹配密码是否正确
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        // 使用表单单路
        http.formLogin()
        .loginPage("/login")
        // 处理表单登陆提交的URL，默认使用/login【POST】，具体查看UsernamePasswordAuthenticationFilter
        .loginProcessingUrl("/authentication/form/login")
        // 成功处理器
        .successHandler(adminAuthenticationSuccessHandler)
        // 失败处理器
        .failureHandler(adminAuthenticationFailureHandler)
        .and()
        // 请求授权
        .authorizeRequests()
        // 过滤OPTIONS请求
        .antMatchers(HttpMethod.OPTIONS).permitAll()
        // 过滤该URL
        .antMatchers("/authentication/form/login", "/login").permitAll()
        // 任何请求
        .anyRequest()
        // 通过自定义requestAuthenticationService类对请求的url进行鉴权校验
        .access("@requestAuthenticationService.isPossessPermission(authentication, request)")
        //都需要身份认证
        //.authenticated()
        // 取消跨站请求防护
        .and().csrf().disable();
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.expressionHandler(expressionHandler);
    }


}
